#include <vector>
#include <iostream>
#include <fstream>
#include <assert.h>
#include <time.h>
#include <math.h>

#include "../../include/GlobalMemory.hpp"

extern void gpu_op(CH::GlobalMemory<int>& a_d, const int& block_dim, int block_num);

int main(int argc, char* argv[])
{
	//how many numbers to reduce
	int data_size = 12345; 

	//num of threads in each block
	int block_dim = 256; 
	
	//block number
	int block_num = (data_size + 2*block_dim - 1)/(2*block_dim);
	
	srand(time(0)); //random num seed
	
	for(int c = 0; c < 200; c++)
	{
		//initialize data source
		std::vector<int> a_h(data_size);

		for(int i = 0; i < data_size; i++) 
			a_h[i] = rand() % 20;

		//transfer to GPU
		CH::GlobalMemory<int> a_d = a_h;

		//launch
		gpu_op(a_d, block_dim, block_num);

		//get GPU result back
		int gpu_res = 0;
		cudaMemcpy(&gpu_res, a_d.get_memory_ptr(), sizeof(int), cudaMemcpyDeviceToHost);

		//calc result on CPU
		int cpu_res = 0;
		for(int i = 0; i < data_size; i++)
			cpu_res += a_h[i];
		
		assert( gpu_res == cpu_res );

	}

}